###############################################################################

# Replication File (Observational): "The Effect of Simultaneous Proposals"
# Klaudia Wegschaider, February 2025

###############################################################################

# STRUCTURE

# This file covers the replication of the observational municipal data.
# For the replication of the experimental data, please see the other file.

# The analyses covered here are included in the appendices.

# I do not explain the purpose of all the steps here. Readers should consult
# this file in combination with the manuscript and appendix.

###############################################################################

# BACKGROUND

# This code is based on R version 4.1.3 (2022-03-10)

# Please load the required packages.

library(kableExtra)
library(modelsummary)
library(tidyr)
library(dplyr)
library(writexl)
library(fixest)
library(plm)
library(tibble)
library(sandwich)
library(clubSandwich)
library(lmtest)

# sessionInfo()
# R version 4.1.3 (2022-03-10)
# other attached packages:
# [1] lmtest_0.9-40       zoo_1.8-12          clubSandwich_0.5.11 sandwich_3.0-1     
# [5] tibble_3.2.1        plm_2.6-1           fixest_0.10.4       writexl_1.4.2      
# [9] dplyr_1.1.2         tidyr_1.3.0         modelsummary_1.0.2  kableExtra_1.4.0 

###############################################################################

# CANTONAL DATA 

# Full cantonal dataset (contains data at cantonal level)
data <- read.csv(file="cantonal_dataset.csv") 
summary(data)
# View(data)

# Subsetting for subsequent analyses (removing extreme versions in pairs)
data_partial <- data[(data$Extreme==0),] 
summary(data_partial)

# Subsetting for subsequent analyses (removing moderate versions in pairs)
data_partial_p <- data[(data$Simultaneous==0),]
summary(data_partial_p)

# MUNICIPAL DATA

# The dataset is not publicly available.
# Please contact Anna Maria Koukal and Patricia Schafer.
# Note that I have made minor correction to the dataset, see Appendix 4.

# loading and preparing the municipal dataset
# Koukal et al dataset (contains data at municipal level)
koukaldata <- read.csv(file="koukaldata.csv") 
summary(koukaldata)
# Subsetting to exclude constiuttional revisions
koukal_single <- koukaldata[(koukaldata$totalrevision==0),] 
# Merging the datasets
mergedata <- merge(data, koukal_single, by="abst_id")
summary(mergedata)
# Removing the extreme proposals from the dataset
mergedata_h <- mergedata[(mergedata$Extreme==0),] 
# Removing the moderate proposals from the dataset
mergedata_p <- mergedata[(mergedata$Simultaneous==0),] 
# Creating a factor variable based on cantonal/municipal ID
# Why? Fixed effect need to be a factor variable
mergedata_h$kt_id_f <- factor(mergedata_h$kt_id) 
mergedata_p$kt_id_f <- factor(mergedata_p$kt_id) 

# View(mergedata_h)
# View(mergedata_p)

###############################################################################

# ANALYSIS OF MUNICIPAL DATA (MAIN HYPOTHESIS)

# Basic model without fixed effects
model1 <- feols(jaA ~ Simultaneous, data = mergedata_h)
summary(model1)

# Basic model with cantonal FE and proposal clustered SE
model2 <- feols(jaA ~ Simultaneous | kt_id_f, data = mergedata_h, cluster = ~ abst_id)
summary(model2)

# Model with controls: inclusiveness
# + cantonal FE and proposal clustered SE
model3 <- feols(jaA ~ Simultaneous + Scale | kt_id_f, data = mergedata_h, cluster = ~ abst_id)
summary(model3)

# Model with controls: inclusiveness, franchise experience
# + cantonal FE and proposal clustered SE
model4 <- feols(jaA ~ Simultaneous + Scale + Experience | kt_id_f, data = mergedata_h, cluster = ~ abst_id)
summary(model4)

# Model with controls: inclusiveness, franchise experience
# + cantonal FE and proposal clustered SE
model5 <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft | kt_id_f, data = mergedata_h, cluster = ~ abst_id)
summary(model5)

# Making the table
muni_models_h <- list(model1, model2, model3, model4, model5)

cm3 <- c('Simultaneous'    = 'Simultaneous moderate, $M_{Sim}$ \\\\ (baseline: non-simultaneous)',
         'Scale'    = 'Inclusiveness (range: 1-6)',
         'Experience' = 'Prior experience',
         'CantonalLeft' = 'Cantonal left')

rows3 <- tribble(~term,          ~Model1,  ~Model2,  ~Model3,  ~Model4,  ~Model5, 
                 'Cantonal FE', 'No', 'Yes', 'Yes', 'Yes', 'Yes',
                 'Proposal clustered SE', 'No', 'Yes', 'Yes', 'Yes', 'Yes')
attr(rows3, 'position') <- c(9, 10)

table3 <-modelsummary(muni_models_h, output = 'kableExtra', type='latex',
                      fmt = 1, 
                      stars = c('*' = .1, '**' = .05, '***' = .01),
                      coef_omit = "Intercept",
                      gof_map = c("nobs"),
                      coef_map = cm3, 
                      escape = FALSE,
                      add_rows = rows3,
                      title = 'Simultaneous Votes in Swiss Referendums (Hypothesis 1)')
table3

###

# ANALYSIS OF MUNICIPAL DATA (ROBUSTNESS CHECK)

# Basic model without fixed effects
model1_p <- feols(jaA ~ Extreme, data = mergedata_p)
summary(model1_p)

# Basic model with FE and proposal clustered SE
model2_p <- feols(jaA ~ Extreme | kt_id_f, data = mergedata_p, cluster = ~ abst_id)
summary(model2_p)

# Model with controls: inclusiveness
# + FE and proposal clustered SE
model3_p <- feols(jaA ~ Extreme + Scale | kt_id_f, data = mergedata_p, cluster = ~ abst_id)
summary(model3_p)

# Model with controls: inclusiveness, franchise experience
# + FE and proposal clustered SE
model4_p <- feols(jaA ~ Extreme + Scale + Experience | kt_id_f, data = mergedata_p, cluster = ~ abst_id)
summary(model4_p)

# Model with controls: inclusiveness, franchise experience, foreign share
# + FE and proposal clustered SE
model5_p <- feols(jaA ~ Extreme + Scale + Experience + CantonalLeft | kt_id_f, data = mergedata_p, cluster = ~ abst_id)
summary(model5_p)

# Making the table
muni_models_p <- list(model1_p, model2_p, model3_p, model4_p, model5_p)

cm4 <- c('Extreme'    = 'Simultaneous extreme, $E_{Sim}$ \\\\ (baseline: non-simultaneous)',
         'Scale'    = 'Inclusiveness (range: 1-6)',
         'Experience' = 'Prior experience',
         'CantonalLeft' = 'Cantonal left')

rows4 <- tribble(~term,          ~Model1,  ~Model2,  ~Model3,  ~Model4,  ~Model5, 
                 'Cantonal FE', 'No', 'Yes', 'Yes', 'Yes', 'Yes',
                 'Proposal clustered SE', 'No', 'Yes', 'Yes', 'Yes', 'Yes')
attr(rows4, 'position') <- c(9, 10)

table4 <-modelsummary(muni_models_p, output = "kableExtra",
                      fmt = 1, 
                      stars = c('*' = .1, '**' = .05, '***' = .01),
                      coef_omit = "Intercept",
                      gof_map = c("nobs"),
                      escape = FALSE,
                      coef_map = cm4,
                      add_rows = rows4,
                      title = 'Simultaneous Votes in Swiss Referendums (Robustness)')
table4

###############################################################################

# MUNICIPAL: ADDIDNG ADDITIONAL CONTROLS

# MUNICIPAL: ADDIDNG ADDITIONAL CONTROLS

# Basic model without fixed effects
model1 <- feols(jaA ~ Simultaneous, data = mergedata_h)
summary(model1)

# Basic model with cantonal FE and proposal clustered SE
model2 <- feols(jaA ~ Simultaneous | kt_id_f, data = mergedata_h, cluster = ~ abst_id)
summary(model2)

# Model with controls: inclusiveness, franchise experience, cantonal left, share of foreigners
# + cantonal FE and proposal clustered SE
model6 <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft + anteil_auslaender | kt_id_f, data = mergedata_h, cluster = ~ abst_id)
summary(model6)

# Model with controls: inclusiveness, franchise experience, cantonal left, share of foreigners
# added: local unemployment among Swiss, share of municipal SP voters
# + cantonal FE and proposal clustered SE
model7 <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft + anteil_auslaender + ALQ_ch | kt_id_f, data = mergedata_h, cluster = ~ abst_id)
summary(model7)

# Model with controls: inclusiveness, franchise experience, cantonal left, share of foreigners
# added: local unemployment among Swiss, mean income
# + cantonal FE and proposal clustered SE
model8 <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft + anteil_auslaender + ALQ_ch + mean_reink | kt_id_f, data = mergedata_h, cluster = ~ abst_id)
summary(model8)

# Model with controls: inclusiveness, franchise experience, cantonal left, share of foreigners
# added: local unemployment among Swiss, share of municipal SP voters, mean income
# + cantonal FE and proposal clustered SE
model9 <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft + anteil_auslaender + ALQ_ch + mean_reink + anteilsp | kt_id_f, data = mergedata_h, cluster = ~ abst_id)
summary(model9)

# Making the table
muni_models_h_appendix <- list(model1, model2, model6, model7, model8, model9)

cm8 <- c('Simultaneous'    = 'Simultaneous moderate, $M_{Sim}$ \\\\ (baseline: non-simultaneous)',
         'Scale'    = 'Inclusiveness (range: 1-6)',
         'Experience' = 'Prior experience',
         'CantonalLeft' = 'Cantonal left',
         'anteil_auslaender' = 'Municipal share foreign pop.',
         'ALQ_ch' = 'Municipal unemployment \\\\ (among Swiss)',
         'mean_reink' = 'Municipal mean income',
         'anteilsp' = 'Municipal SP vote share')

rows3 <- tribble(
  ~term,          ~Model1,  ~Model2,  ~Model6,  ~Model7,  ~Model8,  ~Model9,
  'Cantonal FE',            'No',      'Yes',    'Yes',    'Yes',    'Yes',    'Yes',
  'Proposal clustered SE',  'No',      'Yes',    'Yes',    'Yes',    'Yes',    'Yes')
attr(rows3, 'position') <- c(17, 18)

table3_app <-modelsummary(muni_models_h_appendix, output = 'kableExtra', type='latex',
                          fmt = 1, 
                          stars = c('*' = .1, '**' = .05, '***' = .01),
                          coef_omit = "Intercept",
                          gof_map = c("nobs"),
                          coef_map = cm8, 
                          escape = FALSE,
                          add_rows = rows3,
                          title = 'Simultaneous Votes in Swiss Referendums (Hypothesis 1)')
table3_app

### 

# MUNICIPAL ANALYSIS WITH MUNICIPAL FIXED EFFECTS

# MUNICIPAL: ADDIDNG MUNICIPAL FIXED EFFECTS
panel_municipal_filtered <- mergedata_h %>%
  group_by(ge_id) %>%
  filter(n() > 1) %>%
  ungroup()

# Basic model with municipal FE and proposal clustered SE
model0_local <- feols(jaA ~ Simultaneous, data = mergedata_h)
summary(model0_local)

# Basic model with municipal FE and proposal clustered SE
model1_local <- feols(jaA ~ Simultaneous | ge_id, data = panel_municipal_filtered, cluster = ~ abst_id)
summary(model1_local)

# Model with controls: inclusiveness, franchise experience, cantonal left
# + municipal FE and proposal clustered SE
model2_local <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft | ge_id, data = panel_municipal_filtered, cluster = ~ abst_id)
summary(model2_local)

# Model with controls: inclusiveness, franchise experience, cantonal left
# + municipal FE and proposal clustered SE
model3_local <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft + anteil_auslaender | ge_id, data = panel_municipal_filtered, cluster = ~ abst_id)
summary(model3_local)

# Model with controls: inclusiveness, franchise experience, cantonal left
# added: share of foreigners, local unemployment among Swiss
# + municipal FE and proposal clustered SE
model4_local <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft + anteil_auslaender + ALQ_ch | ge_id, data = panel_municipal_filtered, cluster = ~ abst_id)
summary(model4_local)

# Model with controls: inclusiveness, franchise experience, cantonal left
# added: share of foreigners, local unemployment among Swiss, mean local income
# + municipal FE and proposal clustered SE
model5_local <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft + anteil_auslaender + ALQ_ch + mean_reink | ge_id, data = panel_municipal_filtered, cluster = ~ abst_id)
summary(model5_local)

# Model with controls: inclusiveness, franchise experience, cantonal left
# added: share of foreigners, local unemployment among Swiss, mean local income, share of municipal SP voters
# + municipal FE and proposal clustered SE
model6_local <- feols(jaA ~ Simultaneous + Scale + Experience + CantonalLeft + anteil_auslaender + ALQ_ch + mean_reink + anteilsp | ge_id, data = panel_municipal_filtered, cluster = ~ abst_id)
summary(model6_local)

# Making the table
muni_models_h_fe_appendix <- list(model1_local, model2_local, model3_local, model4_local, model5_local, model6_local)

cm9 <- c('Simultaneous'    = 'Simultaneous moderate, $M_{Sim}$ \\\\ (baseline: non-simultaneous)',
         'Scale'    = 'Inclusiveness (range: 1-6)',
         'Experience' = 'Prior experience',
         'CantonalLeft' = 'Cantonal left',
         'anteil_auslaender' = 'Municipal share foreign pop.',
         'ALQ_ch' = 'Municipal unemployment \\\\ (among Swiss)',
         'mean_reink' = 'Municipal mean income',
         'anteilsp' = 'Municipal Social Democrat \\\\ vote share')

rows4 <- tribble(
  ~term,          ~model1_local,  ~model2_local,  ~model3_local,  ~model4_local,  ~model5_local, ~model6_local,
  'Municipal FE',                 'Yes',    'Yes',    'Yes',    'Yes',    'Yes',  'Yes',
  'Proposal clustered SE',        'Yes',    'Yes',    'Yes',    'Yes',    'Yes',  'Yes')
attr(rows4, 'position') <- c(17, 18)

table_fe_app <-modelsummary(muni_models_h_fe_appendix, output = 'kableExtra', type='latex',
                            fmt = 1, 
                            stars = c('*' = .1, '**' = .05, '***' = .01),
                            coef_omit = "Intercept",
                            gof_map = c("nobs"),
                            coef_map = cm9, 
                            escape = FALSE,
                            add_rows = rows4,
                            title = 'Simultaneous Votes in Swiss Referendums (Hypothesis 1)')
table_fe_app

###############################################################################
# End. Thank you for reading.
###############################################################################